package com.campus.service.impl;

import com.alibaba.fastjson.JSON;
import com.campus.constant.MessageConstant;
import com.campus.constant.RoleConstant;
import com.campus.constant.StatusConstant;
import com.campus.context.CurrentHolder;
import com.campus.exception.UpdateNotAllowedException;
import com.campus.mapper.PostMapper;
import com.campus.pojo.dto.PostCancelDTO;
import com.campus.pojo.dto.PostDTO;
import com.campus.pojo.dto.PostPageQueryDTO;
import com.campus.pojo.dto.PostRejectDTO;
import com.campus.pojo.entity.Post;
import com.campus.pojo.vo.PostStatisticsVO;
import com.campus.pojo.vo.PostVO;
import com.campus.result.PageResult;
import com.campus.service.PostService;
import com.campus.websocket.WebSocketService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class PostServiceImpl implements PostService {
    @Autowired
    private PostMapper postMapper;
    @Autowired
    private WebSocketService webSocketService;

    @Override
    public PageResult<PostVO> pageQuery(PostPageQueryDTO postPageQueryDTO) {
        //1.设置分页参数
        PageHelper.startPage(postPageQueryDTO.getCurrentPage(), postPageQueryDTO.getPageSize());

        //2.前端用户查询的时候 传递的有userId 对于进行中和已完成的帖子，我们应该管理员和用户都能看到 此处置空userId
        Integer status = postPageQueryDTO.getStatus();
        if (status != null) {
            if (status.equals(StatusConstant.POST_STATUS_PROCESS) || status.equals(StatusConstant.POST_STATUS_FINISH)) {
                postPageQueryDTO.setUserId(null);
            }
        }

        //3.调用mapper查询
        Page<PostVO> page = postMapper.pageQuery(postPageQueryDTO);

        //4.封装PageResult并返回
        return new PageResult<>(page.getTotal(), page.getResult());
    }

    @Override
    public PostVO getById(Long id) {
        return postMapper.getById(id);
    }

    @Override
    public void updateStatus(Long id) {
        //1.构建entity对象-post
        Post post = Post.builder()
                .id(id)
                .status(StatusConstant.POST_STATUS_PROCESS)
                .build();

        //2.调用mapper方法 复用
        postMapper.update(post);
    }

    @Override
    public void rejectPost(PostRejectDTO postRejectDTO) {
        //1.构建entity对象-post
        Post post = Post.builder()
                .id(postRejectDTO.getId())
                .status(StatusConstant.POST_STATUS_CANCEL)
                .rejectReason(postRejectDTO.getRejectReason())
                .build();

        //2.调用mapper方法
        postMapper.update(post);

        //3.通过websocket发送消息给用户

        //包装json 数据
        Map<String, Object> map = new HashMap<>();
        map.put("type", 3);//3-审核失败 被拒绝
        map.put("message"," 帖子审核失败提醒!");
        String json = JSON.toJSONString(map);

        //根据帖子id获取用户id
        Long userId = postMapper.getUserId(postRejectDTO.getId());

        //发送消息
        webSocketService.sendMessageToUser(userId, json);



    }

    @Override
    public void cancelPost(PostCancelDTO postRejectDTO) {
        //1.构建entity对象-post
        Post post = Post.builder()
                .id(postRejectDTO.getId())
                .status(StatusConstant.POST_STATUS_CANCEL)
                .cancelReason(postRejectDTO.getCancelReason())
                .build();

        //2.调用mapper方法
        postMapper.update(post);
    }

    @Override
    public void returnItem(Long id) {
        //1.构建entity对象-post
        Post post = Post.builder()
                .id(id)
                .status(StatusConstant.POST_STATUS_FINISH)
                .build();

        //2.调用mapper方法
        postMapper.update(post);
    }

    @Override
    public void claimItem(Long id) {
        //1.构建entity对象-post
        Post post = Post.builder()
                .id(id)
                .status(StatusConstant.POST_STATUS_FINISH)
                .build();

        //2.调用mapper方法
        postMapper.update(post);
    }

    @Override
    public void addPost(PostDTO postDTO) {
        //1.构建entity对象-post
        Post post = new Post();
        //属性拷贝
        BeanUtils.copyProperties(postDTO, post);

        //2.封装其他属性
        //默认为待审核状态
        post.setStatus(StatusConstant.POST_STATUS_WAIT);
        //用户ID
        post.setUserId(CurrentHolder.getCurrentId());

        //3.调用mapper方法
        postMapper.insert(post);

        //4.通知管理员进行审核
        Map<String, Object> map = new HashMap<>();
        map.put("type", 4); //提示管理员审核帖子
        map.put("message", "新帖子待审核：《" + post.getTitle() + "》");
        String json = JSON.toJSONString(map);

        webSocketService.sendMessageToUser(RoleConstant.ADMIN_ROLE_ID, json);


    }

    @Override
    public void updatePost(PostDTO postDTO) {
        //1.只有待审核状态的帖子才能修改 即使前端控制了入口，仍可能存在绕过前端验证的情况
        PostVO postVO = postMapper.getById(postDTO.getId());
        if (!postVO.getStatus().equals(StatusConstant.POST_STATUS_WAIT)) {
            //状态不是待审核状态
            throw new UpdateNotAllowedException(MessageConstant.POST_STATUS_ERROR);
        }

        //2.构建entity对象-post
        Post post = new Post();
        BeanUtils.copyProperties(postDTO, post);
        //status无需修改 此时本就为待审核状态

        //3.调用mapper方法
        postMapper.update(post);
    }

    @Override
    public PostStatisticsVO statistics() {
        //1.统计各个状态的帖子数量
        Integer toBeReviewed = postMapper.countStatus(StatusConstant.POST_STATUS_WAIT);
        Integer inProgress = postMapper.countStatus(StatusConstant.POST_STATUS_PROCESS);
        Integer completed = postMapper.countStatus(StatusConstant.POST_STATUS_FINISH);
        Integer cancelled = postMapper.countStatus(StatusConstant.POST_STATUS_CANCEL);

        //2.封装成VO对象并返回
        return PostStatisticsVO.builder()
                .toBeReviewed(toBeReviewed)
                .inProgress(inProgress)
                .completed(completed)
                .cancelled(cancelled)
                .build();
    }
}
